package viewModel;

import java.util.ArrayList;
import java.util.List;

import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.Sessions;

import Misc.Functions;
import Misc.Variables;
import databaseHelper.WorkedExamDAO;
import datatypes.WorkedExam;


/**
 * ViewModel for WorkedExam (Evaluation Statistics) section
 * @author Rupert
 *
 */
public class WorkedExamViewModel {
	/**
	 * database access
	 */
	private WorkedExamDAO exams = new WorkedExamDAO();
	
		
	/**
	 * List containing all exams
	 */
	private List<WorkedExam> workedExams = new ArrayList<WorkedExam>();
	 
	/**
	 * statistics
	 */
	private int numberOfFailed = 0;
	private int numberOfPassed = 0;
	private double  averageGradeTotal = 0;
	private double averageGradeWoFailed = 0;
	private int numberOfFailedSecond = 0;
	private int numberOfPassedSecond = 0;
	private double  averageGradeTotalSecond = 0;
	private double averageGradeWoFailedSecond = 0;

	private String pdfPath ="";
	/**
	 * check login;
	 * load worked exams and statistics from database
	 * 
	 */
	@Init
    public void init(){
		Session zkSession = Sessions.getCurrent();
		Object tmpObject = zkSession.getAttribute(Variables.workedExamSessionAttribut);
		if(tmpObject == null){
			workedExams =  new ArrayList<WorkedExam>();
			Executions.sendRedirect("login.zul");
		}else{
			int subjectId = new Integer(tmpObject.toString());
			
			if(subjectId> 0){
				
				zkSession = Sessions.getCurrent();
				tmpObject = zkSession.getAttribute(Variables.examPDFPathAttribut);
				pdfPath = tmpObject.toString();
				
				workedExams = exams.findAllofExam(subjectId);
				System.out.println("Anzahl an worked Exams = "+workedExams.size());
				double[] failedInformation = calculateNumberOfFailed();
				double[] failedInformationSecond = calculateNumberOfFailedSecond();
				setNumberOfFailed((int) failedInformation[0]);
				setNumberOfPassed((int) failedInformation[1]);
				setAverageGradeTotal(Functions.roundDoubleToTwoFloatNumber(failedInformation[2] / (failedInformation[0] + failedInformation[1])));
				setAverageGradeWoFailed(Functions.roundDoubleToTwoFloatNumber(failedInformation[3] / (failedInformation[1])));
				setNumberOfFailedSecond((int) failedInformationSecond[0]);
				setNumberOfPassedSecond((int) failedInformationSecond[1]);
				setAverageGradeTotalSecond(Functions.roundDoubleToTwoFloatNumber(failedInformationSecond[2] / (failedInformationSecond[0] + failedInformationSecond[1])));
				setAverageGradeWoFailedSecond(Functions.roundDoubleToTwoFloatNumber(failedInformationSecond[3] / (failedInformationSecond[1])));
				setPdfPath(pdfPath);
			}else{
				Executions.sendRedirect("dashboard.zul");
			}
		}
    }
	
	/**
	 * calculating the statistics.
	 * @return
	 */
	private double[] calculateNumberOfFailed(){
		double[] newArray = new double[4];
		double nbrOfFailed = 0;
		double nbrOfPassed = 0;
		double averageGradeTotal = 0;
		double averageGradeWoFailed = 0;
		
		for(WorkedExam workedExam : workedExams){
			double curGrade = workedExam.getGrade();
			if( curGrade > 4.0){
				nbrOfFailed++;
			}else{
				averageGradeWoFailed =  averageGradeWoFailed + curGrade;
				nbrOfPassed++;
			}
			averageGradeTotal = averageGradeTotal + curGrade;
		}
		
		newArray[0] = nbrOfFailed;
		newArray[1] = nbrOfPassed;
		newArray[2] = averageGradeTotal;
		newArray[3] = averageGradeWoFailed;
		
		return newArray;
	}
	
	/**
	 * calculating the statistics.
	 * @return
	 */
	private double[] calculateNumberOfFailedSecond(){
		double[] newArray = new double[4];
		double nbrOfFailed = 0;
		double nbrOfPassed = 0;
		double averageGradeTotal = 0;
		double averageGradeWoFailed = 0;
		
		for(WorkedExam workedExam : workedExams){
			double curGrade = workedExam.getSecondGrade();
			if( curGrade > 4.0){
				nbrOfFailed++;
			}else{
				averageGradeWoFailed =  averageGradeWoFailed + curGrade;
				nbrOfPassed++;
			}
			averageGradeTotal = averageGradeTotal + curGrade;
		}
		
		newArray[0] = nbrOfFailed;
		newArray[1] = nbrOfPassed;
		newArray[2] = averageGradeTotal;
		newArray[3] = averageGradeWoFailed;
		
		return newArray;
	}
	
	
		
	/**
	 * 
	 * @param grade - must be a valid grade! -> 1.0, 1.3, 1.7, 2.0,..., 3.7, 4.0
	 * @return Count of how many exams with the given grad exist!
	 */
	public int getNumberOfGradesOfCurrentExam(double grade){
		Object tmpObject =Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		if(tmpObject == null)
			return 0;
		int subjectId = new Integer(tmpObject.toString());
		return exams.getNumberOfGrades(grade, subjectId);
	}
	

	
	/************************************************************************************
	 * 
	 * Getters & Setters
	 * 
	 ************************************************************************************/
	
	
	public List<WorkedExam> getExams(){
		return this.workedExams;
	}



	/**
	 * @return the numberOfFailed
	 */
	public int getNumberOfFailed() {
		return numberOfFailed;
	}



	/**
	 * @param numberOfFailed the numberOfFailed to set
	 */
	public void setNumberOfFailed(int numberOfFailed) {
		this.numberOfFailed = numberOfFailed;
	}

	/**
	 * @return the numberOfPassed
	 */
	public int getNumberOfPassed() {
		return numberOfPassed;
	}

	/**
	 * @param numberOfPassed the numberOfPassed to set
	 */
	public void setNumberOfPassed(int numberOfPassed) {
		this.numberOfPassed = numberOfPassed;
	}

	/**
	 * @return the averageGradeTotal
	 */
	public double getAverageGradeTotal() {
		return averageGradeTotal;
	}

	/**
	 * @param averageGradeTotal the averageGradeTotal to set
	 */
	public void setAverageGradeTotal(double averageGradeTotal) {
		this.averageGradeTotal = averageGradeTotal;
	}

	/**
	 * @return the averageGradeWoFailed
	 */
	public double getAverageGradeWoFailed() {
		return averageGradeWoFailed;
	}

	/**
	 * @param averageGradeWoFailed the averageGradeWoFailed to set
	 */
	public void setAverageGradeWoFailed(double averageGradeWoFailed) {
		this.averageGradeWoFailed = averageGradeWoFailed;
	}

	/**
	 * @return the numberOfFailedSecond
	 */
	public int getNumberOfFailedSecond() {
		return numberOfFailedSecond;
	}

	/**
	 * @param numberOfFailedSecond the numberOfFailedSecond to set
	 */
	public void setNumberOfFailedSecond(int numberOfFailedSecond) {
		this.numberOfFailedSecond = numberOfFailedSecond;
	}

	/**
	 * @return the numberOfPassedSecond
	 */
	public int getNumberOfPassedSecond() {
		return numberOfPassedSecond;
	}

	/**
	 * @param numberOfPassedSecond the numberOfPassedSecond to set
	 */
	public void setNumberOfPassedSecond(int numberOfPassedSecond) {
		this.numberOfPassedSecond = numberOfPassedSecond;
	}

	/**
	 * @return the averageGradeTotalSecond
	 */
	public double getAverageGradeTotalSecond() {
		return averageGradeTotalSecond;
	}

	/**
	 * @param averageGradeTotalSecond the averageGradeTotalSecond to set
	 */
	public void setAverageGradeTotalSecond(double averageGradeTotalSecond) {
		this.averageGradeTotalSecond = averageGradeTotalSecond;
	}

	/**
	 * @return the averageGradeWoFailedSecond
	 */
	public double getAverageGradeWoFailedSecond() {
		return averageGradeWoFailedSecond;
	}

	/**
	 * @param averageGradeWoFailedSecond the averageGradeWoFailedSecond to set
	 */
	public void setAverageGradeWoFailedSecond(double averageGradeWoFailedSecond) {
		this.averageGradeWoFailedSecond = averageGradeWoFailedSecond;
	}

	/**
	 * @return the pdfPath
	 */
	public String getPdfPath() {
		return pdfPath;
	}

	/**
	 * @param pdfPath the pdfPath to set
	 */
	public void setPdfPath(String pdfPath) {
		this.pdfPath = pdfPath;
	}
	
	
}
